/*通过setImmediate()进行调度*/

/*
异步方法的定义如下：
下一个事件循环(Tick)才会取出执行
**/
var async = function() {
    process.nextTick(callback);
}

var async = fucntion() {
    process.nextTick(function() {
        var results = something;
        if (error) {
            return callback(error);
        }
        callback(null, results);
    })
}

/* 事件发布/订阅模式 */

/* 订阅事件 */
emitter.on("event1", function (message) {
    console.log(message);
});

/* 发布事件 */
emitter.emit('event1', "I am message!");

/**
  如果对一个事件添加了超过10个监听器，将会得到一条告警。这一处设计与Node自身单
  线程运行有关，设计者认为侦听器太多可能导致内存泄露，所以存在这样一条警告。调用
  emitter.setMaxListeners(0);可以将这个限制去掉。另一方面，由于事件发布引起
  一系列侦听器执行，如果事件相关的侦听器过多，可能存在过多占用CPU的场景。
*/

/**
  为了处理异常，EventEmitter对象对error事件进行了特殊对待。如果运行期间的错误
  触发了error事件，EventEmitter会检查是否有对error事件添加过侦听器。如果添加了
  ，这个错误将会交由该侦听器处理，否则这个错误将会作为异常抛出。如果外部没有捕获
  这个异常，将会引起线程退出。一个健壮的EventEmitter实力应该对error事件做处理。
*/

/* 对于相同的SQL语句，保证在同一个查询开始到结束的过程中永远只有一次。 */
var proxy = new event.EventEmitter();

var status = "ready";
var select = function (callback) {
    proxy.once("selectd", callback);
    if (status === "ready") {
        status = "pending";
        db.select("SQL", function (results) {
            proxy.emit("selected", results);
            status = "ready";
        }
    }
}

/* 多异步协作 */
    /*1*/
    var after = function (times, callback) {
        var count = 0, results = {};
        return function (key, value) {
            results[key] = value;
            count++;
            if (count === times) {
                callback(results);
            }
        };
    };
    var done = after(times, render);

    /*2*/
    var emitter = new events.Emitter();
    var done = after(times, render);
    emitter.on("done", done);
    emitter.on("done", other);
    fs.readFile(template_path, "utf8", function (err, template) {
        emitter.emit("done", "template", template);
    });
    db.query(sql, function (err, data) {
        emitter.emit("done", "data", data);
    });
    l10n.get(function (err, resources) {
        emitter.emit("done", "resources", resources);
    });

    /*3*/
    var proxy = new EventProxy();
    proxy.all("template", "data", "resources", function (template, data, resources) {
        // TODO
    });
    2
    fs.readFile(template_path, "utf8", function (err, template) {
        proxy.emit("template", template);
    });
    db.query(sql, function (err, data) {
        proxy.emit("data", data);
    });
    l10n.get(function (err, resources) {
        proxy.emit("resources", resources);
    });
    
/* EventProxy 类似的扩展方法还有all(), tail(), after(), not(), any()等  */

/**
  Promise/Deferred模式
 */
